import { NextRequest, NextResponse } from "next/server"; import { prisma } from "@/lib/prisma"; import { duplicateFile } from "@/lib/storage"; import { logActivity } from "@/lib/activity"; import { getSpaceIdForFolder } from "@/lib/trash"; /** « rapport.pdf » → « rapport (copie).pdf », puis « rapport (copie 2).pdf »… */ async function copyName(original: string, folderId: string | null): Promise { const m = original.match(/^(.*?)(\.[^.]+)?$/); const stem = m?.[1] ?? original; const ext = m?.[2] ?? ""; const siblings = await prisma.file.findMany({ where: { folderId, deletedAt: null }, select: { name: true } }); const taken = new Set(siblings.map((s) => s.name.toLowerCase())); let candidate = `${stem} (copie)${ext}`; for (let i = 2; taken.has(candidate.toLowerCase()); i++) candidate = `${stem} (copie ${i})${ext}`; return candidate; } export async function POST( request: NextRequest, { params }: { params: { id: string } } ) { const file = await prisma.file.findUnique({ where: { id: params.id } }); if (!file || file.deletedAt) { return NextResponse.json({ error: "File not found" }, { status: 404 }); } // Quota de l'espace partagé (hérité via l'arborescence) const spaceId = await getSpaceIdForFolder(file.folderId); if (spaceId) { const space = await prisma.sharedSpace.findUnique({ where: { id: spaceId } }); if (space) { const agg = await prisma.file.aggregate({ _sum: { size: true }, where: { deletedAt: null, folder: { sharedSpaceId: spaceId } } }); if (Number(agg._sum.size || 0) + Number(file.size) > Number(space.quotaBytes)) { return NextResponse.json({ error: "Quota de l'espace partagé dépassé" }, { status: 413 }); } } } const { storagePath } = await duplicateFile(file.storagePath, file.name); const duplicated = await prisma.file.create({ data: { name: await copyName(file.name, file.folderId), storagePath, // copie octet-à-octet : même état de chiffrement ; on garde la taille en clair d'origine size: file.size, mimeType: file.mimeType, folderId: file.folderId, userId: file.userId, isEncrypted: file.isEncrypted, aiDescription: file.aiDescription, aiTags: file.aiTags, }, }); await logActivity("UPLOAD", duplicated.id, `Duplicated ${file.name}`); return NextResponse.json( { ...duplicated, size: Number(duplicated.size) }, { status: 201 } ); }